Skip to main content

FNP - Testing & Verification - Circuit Testing & Protocol Validation

Summary (Explain Like I’m 5)

Before launching a rocket, NASA doesn’t just hope it works. They:
  • Build a scale model (test circuit on mock data)
  • Simulate every scenario (simulate orbit, landing)
  • Verify math (double-check calculations)
  • Test in production (actual rocket launch with monitoring)
FNP testing works the same way:
  • Unit tests (individual components)
  • Integration tests (protocol flow end-to-end)
  • Circuit verification (Halo2 constraints correct)
  • Load testing (system under stress)
  • Fault injection (what if things break?)

Technical Deep Dive

Test Suite Coverage (126/126 passing):
Unit Tests:
  ├─ M²-ORE (4 tests)
  │  ├─ test_m2ore_keygen: Keypair generation
  │  ├─ test_m2ore_encrypt: Encryption correctness
  │  ├─ test_m2ore_compare: Order-revealing property
  │  └─ test_m2ore_determinism: Same input → same ciphertext

  ├─ LSEQ (5 tests)
  │  ├─ test_lseq_allocation: ID generation in gaps
  │  ├─ test_lseq_ordering: Lexicographic ordering preserved
  │  ├─ test_lseq_conflict_resolution: Concurrent inserts
  │  ├─ test_lseq_encryption: Digit-wise M²-ORE encryption
  │  └─ test_lseq_depth: O(log N) depth guarantee

  ├─ Kyber (19 tests)
  │  ├─ test_kyber_keygen: MLWE keypair generation
  │  ├─ test_kyber_encaps: IND-CCA2 encapsulation
  │  ├─ test_kyber_decaps: Shared secret recovery
  │  ├─ test_kyber_decapsulation_failure: Invalid ciphertexts rejected
  │  ├─ test_kyber_ntt: Number-theoretic transform correctness
  │  └─ 14 additional property-based tests

  ├─ Halo2 Circuits (7 tests - Python spec validation)
  │  ├─ test_range_check_chip: Prove 0 ≤ x < 2^256
  │  ├─ test_comparison_chip: Prove a < b < c
  │  ├─ test_m2ore_chip: Order-revelation verification
  │  ├─ test_kyber_chip: Key encapsulation verification
  │  ├─ test_insert_proof_circuit: Full insert proof
  │  ├─ test_delete_proof_circuit: Full delete proof
  │  └─ test_proof_determinism: Deterministic proof generation

  └─ Protocol (11 tests)
     ├─ test_protocol_insert_operation: Single insertion
     ├─ test_protocol_concurrent_inserts: Multi-user conflict resolution
     ├─ test_protocol_causal_consistency: Lamport clock ordering
     ├─ test_protocol_replay_detection: Duplicate operation rejection
     ├─ test_protocol_key_rotation: M²-ORE key refresh
     └─ 6 additional integration tests

Integration Tests (42 tests):
  ├─ End-to-End Protocol Flow
  │  ├─ test_e2e_single_user_editing: One user, 100 operations
  │  ├─ test_e2e_two_user_concurrent: Simultaneous edits, conflict resolution
  │  ├─ test_e2e_three_user_merge: 3 users, random operations
  │  └─ test_e2e_offline_sync: Offline edits, sync on reconnect

  ├─ Server Verification
  │  ├─ test_server_blind_verification: Proof verification without keys
  │  ├─ test_server_m2ore_comparison: Deterministic ordering
  │  ├─ test_server_operation_merge: CRDT semantics
  │  └─ test_server_access_control: Permission checks

  ├─ Mobile WASM
  │  ├─ test_wasm_proof_verification: Client-side verification
  │  ├─ test_wasm_kyber_encaps: Mobile Kyber performance
  │  ├─ test_wasm_memory_usage: <50MB heap usage
  │  └─ test_wasm_latency: <500ms total

  └─ Docker Deployment (8 tests)
     ├─ test_docker_compose_validation: Valid YAML
     ├─ test_docker_network_connectivity: Services communicate
     ├─ test_docker_postgres_persistence: Data survives restart
     └─ 5 additional deployment tests

Kubernetes Tests (8 tests):
  ├─ test_k8s_base_manifests: Valid YAML, schemas correct
  ├─ test_k8s_replicas_healthy: All pods running
  ├─ test_k8s_service_discovery: DNS resolution works
  ├─ test_k8s_hpa_scaling: Scales up/down on metrics
  ├─ test_k8s_persistence: PVC mounts correctly
  └─ 3 additional infrastructure tests

Performance Tests (20+ tests):
  ├─ Proof Generation Benchmarks
  │  ├─ bench_halo2_insert_proof: 1.2ms ± 0.3ms target
  │  ├─ bench_halo2_delete_proof: 1.2ms ± 0.3ms target
  │  └─ bench_halo2_verification: <16ms on mobile target

  ├─ Cryptography Benchmarks
  │  ├─ bench_m2ore_encryption: <1ms per operation
  │  ├─ bench_m2ore_comparison: <100 microseconds
  │  ├─ bench_kyber_encapsulation: <3ms
  │  └─ bench_kyber_decapsulation: <4ms

  └─ Protocol Benchmarks
     ├─ bench_protocol_insert_latency: P99 < 500ms
     ├─ bench_protocol_throughput: >1000 ops/sec
     └─ bench_protocol_scaling: Linear scaling to 100 ops/sec/pod

Stress Tests (10+ tests):
  ├─ test_stress_1000_concurrent_users: System under load
  ├─ test_stress_10000_operations: Large document
  ├─ test_stress_network_latency: Simulated high latency
  ├─ test_stress_packet_loss: Simulated 5% packet loss
  ├─ test_stress_byzantine_replicas: Malicious operations rejected
  └─ test_stress_cascading_failures: Replica failures isolated

Property-Based Tests (Hypothesis):
  ├─ test_lseq_ordering_preserved: ∀ insertions, order maintained
  ├─ test_crdt_commutativity: ∀ orderings, merge result identical
  ├─ test_kyber_determinism: ∀ inputs, encapsulation deterministic
  └─ test_m2ore_security: ∀ messages, ordering revealed, values hidden
Circuit Verification (Halo2 Rust Implementation):
#[cfg(test)]
mod tests {
    use halo2_proofs::dev::MockProver;
    use halo2_proofs::pasta::Fp;

    #[test]
    fn test_insert_proof_circuit() {
        // Setup: circuit configuration
        let mut circuit = InsertProofCircuit::default();

        // Witness: private inputs (only prover knows)
        circuit.witness = InsertWitness {
            lseq_position: Fp::from(500u64),
            kyber_shared_secret: vec![0x01u8; 32],
            replica_signature: vec![/* signature bytes */],
            lamport_clock: 5u32,
        };

        // Public input: known to verifier
        let public_input = vec![
            Fp::from(500u64),  // encrypted position
            Fp::from(1234u64), // kyber ciphertext hash
            Fp::from(5u32),    // lamport clock
        ];

        // Create mock prover (simulates circuit)
        let k = 18; // 2^18 = 262,144 rows
        let mut prover = MockProver::run(k, &circuit, vec![public_input]).unwrap();

        // Verify all constraints satisfied
        assert!(prover.verify().is_ok());
    }

    #[test]
    fn test_comparison_chip_correctness() {
        // Verify: a < b → constraint satisfied
        // Verify: a > b → constraint NOT satisfied
        // Verify: a = b → constraint NOT satisfied

        let a = Fp::from(100u64);
        let b = Fp::from(200u64);

        let circuit = ComparisonChip::new();
        let result = circuit.constrain_less_than(a, b);

        assert!(result); // 100 < 200 ✓
    }

    #[test]
    fn test_merkle_chip_membership() {
        // Prove: element is in merkle tree at specific path
        let element = Fp::from(0x1234u64);
        let root = Fp::from(0xabcdu64);
        let path = vec![
            Fp::from(0x5678u64),
            Fp::from(0x9abcu64),
            Fp::from(0xdefu64),
        ];

        let circuit = MerkleChip::new();
        let verified = circuit.verify_membership(element, root, &path);

        assert!(verified);
    }
}
Load Testing (Apache JMeter / k6):
// k6 load test
import http from "k6/http";
import { check } from "k6";

export const options = {
    stages: [
        { duration: "30s", target: 100 }, // Ramp up 100 users
        { duration: "1m", target: 500 }, // Ramp to 500 users
        { duration: "30s", target: 1000 }, // Ramp to 1000 users
        { duration: "1m", target: 1000 }, // Stay at 1000
        { duration: "30s", target: 0 }, // Ramp down
    ],
    thresholds: {
        http_req_duration: ["p(99)<500"], // P99 < 500ms
        http_req_failed: ["rate<0.01"], // <1% failure
    },
};

export default function () {
    const payload = JSON.stringify({
        operation: "INSERT",
        position: Math.random() * 10000,
        content: "H",
        lamport_clock: 1,
    });

    const response = http.post("http://fnp-server:8000/verify/insert", payload, {
        headers: { "Content-Type": "application/json" },
    });

    check(response, {
        "status 200": (r) => r.status === 200,
        "latency < 500ms": (r) => r.timings.duration < 500,
        "proof valid": (r) => r.body.includes("proof"),
    });
}

Mermaid Diagrams

Key Terms

  • MockProver → Simulates circuit without cryptographic overhead; fast verification
  • Constraint System → Polynomial equations that must evaluate to zero
  • IND-CCA2 → Security property; indistinguishability under chosen-ciphertext attack
  • Property-Based Testing → Generate random inputs, verify invariants hold
  • Stress Testing → Push system to limits; observe failure modes
  • Load Testing → Simulate real-world user load; measure latency/throughput
  • Byzantine Fault → Malicious replica sending invalid operations
  • SLA Compliance → Latency, throughput, availability targets met

Q/A

Q: Why use MockProver instead of real Halo2 verification? A: MockProver is fast (milliseconds) and deterministic, good for unit tests. Real Halo2 verification with IPA is slower (milliseconds) but necessary for production. Unit tests: MockProver. Integration tests: real proofs. Q: How are concurrent inserts tested? A: Property-based test: generate random insertion sequences for 3 replicas. Verify: (1) All sequences produce identical final document regardless of order, (2) No conflicts, (3) CRDT invariants maintained. Run 10,000 randomized sequences. Q: What happens if a test fails under load? A: Automated bisect: reduce user count, re-run. Identify exact threshold. Check metrics: CPU%, memory, network I/O. If CPU maxed, bottleneck is compute (cryptography). If memory maxed, memory leak. Profile with Prometheus. Q: Are security tests automated? A: Yes. Fault injection tests: (1) Corrupt proofs, verify rejection, (2) Replay operations, verify detection, (3) Invalid signatures, verify rejection. Byzantine test: malicious replica sending junk operations rejected by honest ones.

Example / Analogy

Bridge Testing Analogy:
  • Unit tests: Test individual cables (Kyber, M²-ORE, LSEQ components)
  • Integration tests: Test cable assembly (protocol flow)
  • Load tests: Drive 10,000 cars across bridge simultaneously
  • Stress tests: Drive 50,000 cars, add wind, simulate earthquakes
  • Performance tests: Measure speed (P99 latency), throughput
  • Security tests: Try to sabotage (corrupt load, cut cables) - bridge rejects

Cross-References: Halo2 Circuits, FNP Protocol Flow, Deployment Verification Category: Testing | Quality Assurance | Verification | DevOps Difficulty: Advanced ⭐⭐⭐⭐ Updated: 2025-11-28